package com.GB26875_3_2011.util;

import io.netty.buffer.ByteBuf;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
import java.util.Locale;

/**
 * @author 蒋仕国
 * @projectName GB26875_3_211
 * @ClassName ByteUtils
 * @date 2025-01-13 09:36
 * @Description: TODO []
 */

public class ByteUtils {
    public static int[] byteToBitArray(byte... byteArray) {
        int[] bitArray = new int[byteArray.length * 8]; // 创建一个长度为byte数组长度乘8的int类型数组，用于存储bit位
        for (int i = 0; i < byteArray.length; i++) { // 遍历byte数组
            int b = byteArray[i] & 0xFF; // 将byte值转换为int类型，并获取其低8位
            for (int j = 0; j < 8; j++) { // 遍历bit位，获取每个bit位的状态
                bitArray[i * 8 + j] = (b >> j) & 1;
            }
        }
        return bitArray;
    }

    public static void main(String[] args) {
        int[] ints = byteToBitArray((byte)1,(byte) 12);
        System.out.println(Arrays.toString(ints));
    }
    public static byte hex2byteOne(String hex) {
        return (byte) Integer.parseInt(hex, 16);
    }
    //toBcdBytes
    public static byte[] toBcdBytes(String hex) {
        hex = hex.toUpperCase(Locale.ROOT);
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] charArray = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(charArray[pos]) << 4 | toByte(charArray[pos + 1]));
        }
        return result;
    }

    // BCD码转换成String
    public static String bcdToHexString(byte bcd) {
        int ch1 = (bcd >> 4) & 0x0f;
        int ch2 = (bcd & 0x0f);
        return ch1 + "" + ch2;
    }

    // 数组转字符串
    public static String bcdToHexString(byte[] bcd) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bcd) {
            sb.append(bcdToHexString(b));
        }
        return sb.toString();
    }

    /**
     * 一个byte转换成BCD数据类型； 高四位 一个十六进制一位数，低四位 一个十六进制一位数 ，组成一个字节的hex
     * @param b
     * @return
     */
    public static String getBcd(byte b) {
        int ch1 = (b >> 4) & 0x0f;
        int ch2 = (b & 0x0f);
        return ch1 + "" + ch2;
    }

    /**
     * 读取Intern的字节数组，去除第一个字节
     * @param data
     * @return
     */
    public static byte[] getThreeBytes(Integer data) {
        byte[] bytes = new byte[3];
        bytes[0] = (byte) ((data >> 16) & 0xff);
        bytes[1] = (byte) ((data >> 8) & 0xff);
        bytes[2] = (byte) (data & 0xff);
        return bytes;
    }

    public static String bytes2HexStr(byte[] array) {
        if (null == array || array.length < 1) {
            return "";
        }
        StringBuilder sb = new StringBuilder(array.length);
        String sTemp;
        for (byte b : array) {
            sTemp = Integer.toHexString(0xff & b);
            if (sTemp.length() < 2) {
                sb.append(0);
            }
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

    /**
     * bytes2HexStr 携带0x
     * @param array
     * @return
     */
    public static String bytes2FullHexStr(byte[] array) {
        StringBuilder sb = new StringBuilder(array.length);
        sb.append("0x");
        String sTemp;
        for (int i = 0; i < array.length; i++) {
            sTemp = Integer.toHexString(0xFF & array[i]);
            if (sTemp.length() < 2) {
                sb.append(0);
            }
            sb.append(sTemp);
            if (i < array.length - 1) {
                sb.append("0x");
            }
        }
        return sb.toString().toLowerCase();
    }

    public static short[] toShortArray(byte[] src) {
        if (src.length % 2 != 0) {
            throw new RuntimeException("toShortArray : byte size must %2 = 0");
        }
        short[] dst = new short[src.length / 2];
        for (int i = 0, k = 0; i < src.length; ) {
            dst[k++] = (short) ((src[i++] & 0xff) | ((src[i++] & 0xff) << 8));
        }
        return dst;
    }

    public static byte[] hexStr2Bytes(String hex) {
        if (hex==null || hex.equals("")) {
            return new byte[0];
        }
        hex = hex.toUpperCase(Locale.ROOT);
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] chars = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(chars[pos]) << 4 | toByte(chars[pos + 1]));
        }
        return result;
    }

    private static int toByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }


    /**
     * 读取Buf中剩余的所有字节
     * @param msg  Buf
     * @return 读到的字节数组
     */
    public static byte[] readReadableBytes(ByteBuf msg, boolean needRelease) {
        byte[] content = new byte[msg.readableBytes()];
        msg.readBytes(content);
        // 讀取完畢之後釋放這個ByteBuf
        if (needRelease) {
            msg.release();
        }
        return content;
    }

    public static byte[] readReadableBytes(ByteBuf msg) {
        return readReadableBytes(msg, false);
    }

    // 把 1 0 0 0数据转换为 0 0 0 1 并且转换为int
    public static int readIntDesc(ByteBuf buffer){
        byte[] bytes = new byte[4];
        byte[] desc = new byte[4];
        buffer.readBytes(bytes);
        for (int i = 0; i < 4; i++) {
            desc[i] = bytes[4 - i - 1];
        }
        return bytes2int(desc);
    }

    public static int bytes2int(byte[] data) {
        int mask = 0xff;
        int temp = 0;
        int n = 0;
        for (int i = 0; i < data.length; i++) {
            n <<= 8;
            temp = data[i] & mask;
            n |= temp;
        }
        return n;
    }

    public static short[] bytesToShorts(byte[] bytes, ByteOrder byteOrder) {
        if (bytes == null || bytes.length % 2 != 0) {
            throw new RuntimeException("bytes To Short： bytes.length % 2 = 0 !!!!");
        }
        short[] result = new short[bytes.length/2];
        ByteBuffer.wrap(bytes).order(byteOrder).asShortBuffer().get(result);
        return result;
    }

    // 从ByteBuffer中读取length个字节【】 返回是字节数组
    public static byte[] readSomeByte(int length, ByteBuf byteBuf) {
        byte[] bytes = new byte[length];
        byteBuf.readBytes(bytes);
        return bytes;
    }

    public static String readSomeByteToHex(int length, ByteBuf byteBuf) {
        return bytes2HexStr(readSomeByte(length, byteBuf));
    }

}
